package com.momochen.demo;

import com.momochen.demo.storage.EcgStorage;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.MathUtil;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by momochen on 2017/3/17.
 */
public class ServiceTcpHandler extends SimpleChannelInboundHandler {
    private volatile static long DATA_SIZE = 0;
    private volatile static boolean IS_FIRST = false;

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    EcgStorage ecgStorage;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        System.out.println(sdf.format(new Date()) + "===>" + ctx.channel().remoteAddress() + " Connected");
        DATA_SIZE = 0;
        IS_FIRST = true;
        ecgStorage = new EcgStorage();
//        Channel incoming = ctx.channel();
//        System.out.println("SimpleChatClient:" + incoming.remoteAddress() + "在线");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ch, Object msg) throws Exception {
        System.out.println(sdf.format(new Date()) + "===> receive data：");

        if (msg == null) {
            System.out.println(sdf.format(new Date()) + "===> NULL ");
            return;
        }

//        ByteBuf buf = (ByteBuf) msg;
//        byte[] req = new byte[buf.readableBytes()];
//        buf.readBytes(req);

//        for (int i=0;i<req.length;i++){
//            System.out.print(Integer.toHexString(req[i]));
//        }
//        System.out.println(sdf.format(new Date()) + "===>" + bytesToHexString(req));
        byte[] req = (byte[]) msg;
        DATA_SIZE += req.length;

        String str = "";
        if (IS_FIRST) {
//            System.out.println(sdf.format(new Date()) + "===>(" + DATA_SIZE + "):" + bytesToHexString(req, req.length));
            str = sdf.format(new Date()) + "===>(" + DATA_SIZE + "):" + bytesToHexString(req, req.length);
            IS_FIRST = false;
        } else {
//            System.out.println(sdf.format(new Date()) + "===>(" + DATA_SIZE + "):" + bytesToHexString(req, 10));
            str = sdf.format(new Date()) + "===>(" + DATA_SIZE + "):" + bytesToHexString(req, 10);
        }

        System.out.println(str);
        if (ecgStorage != null) {
            ecgStorage.writeData(str + "\n");
        }

//        ch.writeAndFlush(new byte[]{'A'}).addListener(new ChannelFutureListener() {
//            @Override
//            public void operationComplete(ChannelFuture channelFuture) throws Exception {
//                if (channelFuture.isSuccess()) {
//                    System.out.println(sdf.format(new Date()) + "===>success");
//                } else {
//                    System.out.println(sdf.format(new Date()) + "===>failure");
//                }
//            }
//        });
//        NettyChannel.channel = (SocketChannel) ch.channel();
//        ReferenceCountUtil.release(o);
//        while (true) {
//            List<Integer> datass = new ArrayList<>();
//            for (int i = 0; i < ECG_DATA.length; i++) {
//                datass.add(ECG_DATA[i]);
//            }
//
//            NettyChannel.sendMsg(GsonUtlis.getGson().toJson(new ECGDATAMsg((byte) 1,datass)));
//
//            Thread.sleep(1000);
//        }

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
//        NettyChannel.channel = null;
        System.out.println(sdf.format(new Date()) + "===>" + ctx.channel().remoteAddress() + " Disconnect");
        if (ecgStorage != null) {
            ecgStorage.close();
        }
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        super.channelUnregistered(ctx);
//        System.out.println(sdf.format(new Date()) + "===>" + ctx.channel().remoteAddress() + " Disconnect");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //super.exceptionCaught(ctx, cause);
        System.out.println(sdf.format(new Date()) + "===>" + cause.getMessage());
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
//        super.channelReadComplete(ctx);
//        ctx.flush();
    }

    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                /*读超时*/
                System.out.println("===服务端===(READER_IDLE 读超时)");
                ctx.disconnect();
            } else if (event.state() == IdleState.WRITER_IDLE) {
                /*写超时*/
                System.out.println("===服务端===(WRITER_IDLE 写超时)");
            } else if (event.state() == IdleState.ALL_IDLE) {
                /*总超时*/
                System.out.println("===服务端===(ALL_IDLE 总超时)");
            }
        }
    }

    public static String bytesToHexString(byte[] src, int lenght) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }

//        int lenght = src.length;
        int size = src.length;
        if (lenght > size) {
            lenght = size;
        }

        for (int i = 0; i < lenght; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv + " ");
        }
        return stringBuilder.toString();
    }
}
